/*
 * Copyright (c) 2021
 * User:魔金多商户商城
 * File:TcMemberServiceImpl.java
 * Date:2021/01/11 21:00:11
 */

package com.ruoyi.tc.service.impl;


import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.md5.MojinPasswordEncoder;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.tc.domain.TcMember;
import com.ruoyi.tc.mapper.TcMemberMapper;
import com.ruoyi.tc.service.ITcMemberLevelService;
import com.ruoyi.tc.service.ITcMemberService;
import com.ruoyi.util.PageHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 会员Service业务层处理
 *
 * @author 魔金商城
 * @date 2020-07-25
 */

@Service
public class TcMemberServiceImpl implements ITcMemberService {
    private static final Logger log = LoggerFactory.getLogger(TcMemberServiceImpl.class);
    /**
     * 注入redis服务
     */
    @Autowired
    private RedisCache redisService;
    /**
     * jwt密钥
     */
    @Value("${token.secret}")
    private String jwtSecretKey;
    @Autowired
    private TcMemberMapper TcMemberMapper;

    /**
     * 调试日志
     */
    private Logger logger = LoggerFactory.getLogger(TcMemberServiceImpl.class);
    

    /**
     * 注入会员等级服务接口
     */
    @Autowired
    private ITcMemberLevelService customerLevelService;


    /**
     * 密码工具类
     */
    @Autowired
    @Lazy
    private MojinPasswordEncoder mojinPasswordEncoder;




    @Override
    public TcMember queryCustomerWithNoPasswordById(long id) {
        logger.debug("queryCustomerById and id:{}", id);
        TcMember customer = queryCustomerInfoById(id);
        if (Objects.isNull(customer)) {
            logger.error("member is not exist and id :{}", id);
            return customer;
        }
        return customer.clearPassword();
    }


    /**
     * 根据会员id查询会员信息(包含密码信息)
     *
     * @param id 会员id
     * @return 返回会员信息
     */
    @Override
    public TcMember queryCustomerInfoById(long id) {
        logger.debug("queryCustomerInfoById and id:{}", id);
        return TcMemberMapper.queryCustomerById(id);
    }

    @Override
    public TcMember queryCustomerWithCustomerLevel(long id) {
        logger.debug("queryCustomerWithCustomerLevel and id :{}", id);
        TcMember customer = TcMemberMapper.queryCustomerById(id);
        if (Objects.isNull(customer)) {
            logger.error("member is not exist and id :{}", id);
            return customer;
        }
        return customer;
    }


    /**
     * 添加用户
     *
     * @param customer 用户对象
     * @return 主键id
     */
    @Override
    public int addCustomer(TcMember customer) {
        logger.debug("addCustomer and member :{}", customer);

        // 设置会员密码
        customer.setPassword(mojinPasswordEncoder.encode(customer.getPassword()));
        customer.setConsumptionAmount(BigDecimal.ZERO);
        //设置自己的推荐码
        customer.addSelfRecommondCode();

        // 如果有推荐人 则查询推荐人信息
        if (customer.hasRecommonded()) {
            // 推荐人
            TcMember recommonded = TcMemberMapper.queryCustomerByRecommondCode(customer.getRecommondCode(), customer.getStoreId());

            // 如果推荐人不存在  则返回错误
            if (Objects.isNull(recommonded)) {
                logger.error("addCustomer fail due to recommoned is not exist...and code:{}", customer.getRecommondCode());
                return -10;
            }
            // 设置推荐人的会员id
            customer.setRecommended(recommonded.getId());
            customer.setInterest(recommonded.getNickname());
            // 设置会员的二级推荐人/ 推荐人的推荐人
            customer.setSRecommended(recommonded.getRecommended());
        }
        customer.setCreateTime(new Date());

        TcMemberMapper.insertTcMember(customer);
        return Math.toIntExact(customer.getId());
    }

    /**
     * 自动添加用户 用于免密登录场景
     *
     * @param customer 用户对象
     * @return 主键id
     */
    @Override
    public Long autoAddCustomer(TcMember customer) {
        logger.debug("addCustomer and member :{}", customer);
        //设置自己的推荐码
        customer.addSelfRecommondCode();
        // 设置会员密码
        customer.setPassword(mojinPasswordEncoder.encode(customer.getPassword()));

        customer.setCreateTime(new Date());
        TcMemberMapper.insertTcMember(customer);
        return customer.getId();
    }

    @Override
    public int updateCustomer(TcMember customer) {
        logger.debug("updateCustomer and member:{}", customer);
        if (Objects.isNull(customer)) {
            logger.error("updateCustomer fail due to member is null...");
            return 0;
        }
        if (!StringUtils.isEmpty(customer.getRecommondCode())) {
            TcMember oldCustomer = TcMemberMapper.queryCustomerById(customer.getId());
            if (-1 != oldCustomer.getRecommended()) {
                logger.error("updateCustomer fail :already has recommendCode");
                return -2;
            }
            //查询推荐人
            TcMember recommendCustomer = TcMemberMapper.queryCustomerByRecommondCode(customer.getRecommondCode(), customer.getStoreId());
            if (Objects.isNull(recommendCustomer)) {
                logger.error("updateCustomer fail : queryCustomerByRecommondCode fail ");
                return -3;
            }
            if (customer.getId().equals(recommendCustomer.getId())) {
                logger.error("updateCustomer fail : recommendCustomer  is self  ");
                return -4;
            }
            customer.setRecommended(recommendCustomer.getId());
            customer.setInterest(recommendCustomer.getNickname());
        }
        if (com.ruoyi.common.utils.StringUtils.isNotEmpty(customer.getPaypassword())) {
            customer.setPaypassword(mojinPasswordEncoder.encode(customer.getPaypassword()));
        }
        return TcMemberMapper.updateTcMember(customer);
    }

    @Override
    public TcMember queryCustomerByName(String userName, long storeId) {
        logger.debug("queryCustomerByName and userName:{}", userName);

        if (StringUtils.isEmpty(userName)) {
            logger.error("queryCustomerByName fail due to userName is empty ....");
            return null;
        }

        Map<String, Object> params = new HashMap<>();
        params.put("username", userName);
        params.put("storeId", storeId);
        return TcMemberMapper.queryCustomerByName(params);
    }


    @Override
    public int updateLoginTime(long customerId) {
        return TcMemberMapper.updateLoginTime(customerId);
    }

    @Override
    public int isMobileExist(String mobile, long storeId) {
        logger.debug("isMobileExist and mobile :{}", mobile);

        if (StringUtils.isEmpty(mobile)) {
            logger.error("mobile is empty.....");
            return 0;
        }
        return TcMemberMapper.queryByMobile(mobile, storeId);
    }

    @Override
    public int isEmailExist(String email, long storeId) {
        logger.debug("isEmailExist and mobile :{}", email);

        if (StringUtils.isEmpty(email)) {
            logger.error("mobile is empty.....");
            return 0;
        }
        return TcMemberMapper.queryByEmail(email, storeId);
    }

    @Override
    public int updatePassword(long customerId, String password) {
        logger.debug("updatePassword and customerId:{}", customerId);
        Map<String, Object> params = new HashMap<>();
        params.put("customerId", customerId);
        params.put("password", mojinPasswordEncoder.encode(password));
        return TcMemberMapper.updatePassword(params);
    }

    @Override
    public int updatePayPassword(long customerId, String payPassword) {
        logger.debug("updatePayPassword and customerId:{}", customerId);
        Map<String, Object> params = new HashMap<>();
        params.put("customerId", customerId);
        params.put("payPassword", mojinPasswordEncoder.encode(payPassword));
        return TcMemberMapper.updatePayPassword(params);
    }

    @Override
    public int bindNewMobile(long customerId, String mobile) {
        logger.debug("bindNewMobile and customerId:{} \r\n mobile:{}", customerId, mobile);
        Map<String, Object> params = new HashMap<>();
        params.put("customerId", customerId);
        params.put("mobile", mobile);
        return TcMemberMapper.bindNewMobile(params);
    }

    @Override
    public int updatePasswordByMobile(String mobile, String password, long storeId) {

        logger.debug("updatePasswordByMobile and mobile:{}", mobile);

        Map<String, Object> params = new HashMap<>();
        params.put("mobile", mobile);
        params.put("storeId", storeId);
        params.put("password", mojinPasswordEncoder.encode(password));
        return TcMemberMapper.updatePasswordByMobile(params);
    }


    @Override
    public int updateCustomerConsumptionAmount(long customerId, BigDecimal orderMoney) {
        logger.debug("updateCustomerConsumptionAmount and customerId:{} \r\n orderMoney:{}", customerId, orderMoney);
        Map<String, Object> params = new HashMap<>();
        params.put("customerId", customerId);
        params.put("orderMoney", orderMoney);
        return TcMemberMapper.updateCustomerConsumptionAmount(params);
    }

    @Override
    public int updateCustomerConsumptionAmountByAdmin(long customerId, BigDecimal money) {
        logger.debug("updateCustomerConsumptionAmountByAdmin and customerId:{} \r\n orderMoney:{}", customerId, money);
        Map<String, Object> params = new HashMap<>();
        params.put("customerId", customerId);
        params.put("orderMoney", money);
        TcMember customer = TcMemberMapper.queryCustomerById(customerId);
        if (!customer.checkConsumptionAmount(money)) {
            logger.error("updateCustomerConsumptionAmountByAdmin fail : will be minus");
            return -1;
        }
        return TcMemberMapper.updateCustomerConsumptionAmount(params);
    }


    @Override
    public int updateSignNum(long customerId, boolean continueFlag) {
        logger.debug("updateSignNum and customerId:{}\r\n continueFlag:{}", customerId, continueFlag);
        Map<String, Object> params = new HashMap<>();
        params.put("customerId", customerId);
        params.put("continueFlag", continueFlag);
        return TcMemberMapper.updateSignNum(params);
    }

    @Override
    public int updateCustomerCommission(long customerId, BigDecimal commission) {
        logger.debug("updateCustomerCommission and customerId:{} \r\n commission:{}", customerId, commission);
        Map<String, Object> params = new HashMap<>();
        params.put("customerId", customerId);
        params.put("commission", commission);
        return TcMemberMapper.updateCustomerCommission(params);
    }

    @Override
    public List<TcMember> queryCustomersByIds(List<Long> ids, long storeId) {
        logger.debug("queryCustomersByIds and ids:{}", Arrays.toString(ids.toArray()));
        return CollectionUtils.isEmpty(ids) ? new ArrayList<>() : TcMemberMapper.queryCustomersByIds(ids, storeId);
    }

    @Override
    public List<TcMember> queryAllCustomer() {
        logger.debug("queryAllCustomer...");
        return TcMemberMapper.queryAllCustomer();
    }

    @Override
    public int queryNewCustomerToday() {
        logger.debug("begin to queryNewCustomerToday .....");
        return TcMemberMapper.queryNewCustomerToday();
    }

    @Override
    public int queryNewCustomerThisWeek() {
        logger.debug("begin to queryNewCustomerThisWeek .....");
        return TcMemberMapper.queryNewCustomerThisWeek();
    }



    @Override
    public List<String> queryAllCustomerMobileForCreateStore() {
        logger.debug("queryAllCustomerMobile....");
        return TcMemberMapper.queryAllCustomerMobileForCreateStore();
    }

    @Override
    public int bindCustomerRecommendCode(String recommendCode, long customerId) {
        logger.debug("bindCustomerRecommendCode and recommendCode:{} \r\n customerId:{}", recommendCode, customerId);
        //查询用户
        TcMember customer = TcMemberMapper.queryCustomerById(customerId);
        if (Objects.isNull(customer)) {
            logger.error("bindCustomerRecommendCode fail : member is null");
            return -1;
        }
        if (-1 != customer.getRecommended()) {
            logger.error("bindCustomerRecommendCode fail :already has recommendCode");
            return -2;
        }
        //查询推荐人
        TcMember recommendCustomer = TcMemberMapper.queryCustomerByRecommondCode(recommendCode, customer.getStoreId());
        if (Objects.isNull(recommendCustomer)) {
            logger.error("bindCustomerRecommendCode fail : queryCustomerByRecommondCode fail ");
            return -3;
        }
        if (customer.getId().equals(recommendCustomer.getId())) {
            logger.error("bindCustomerRecommendCode fail : recommendCustomer  is self  ");
            return -4;
        }
        TcMember updateCustomer = new TcMember();
        updateCustomer.setId(customer.getId());
        updateCustomer.setRecommended(recommendCustomer.getId());
        updateCustomer.setInterest(recommendCustomer.getNickname());
        return TcMemberMapper.updateCustomer(updateCustomer);
    }

    @Override
    public PageHelper<TcMember> querySpreadCustomerByCustomerId(PageHelper<TcMember> pageHelper, long cusomerId) {
        Map<String, Object> params = new HashMap<>();
        params.put("customerId", cusomerId);
        return pageHelper.setListDates(TcMemberMapper.querySpreadCustomerByCustomerId(
                pageHelper.getQueryParams(params, TcMemberMapper.querySpreadCustomerCountByCustomerId(cusomerId))));
    }

    @Override
    public PageHelper<TcMember> querySpreadCustomerList(PageHelper<TcMember> pageHelper, long storeId) {
        return null;
    }

    @Override
    public List<TcMember> querySpreadCustomerByCustomerId(long customerId) {
        return null;
    }

    @Override
    public int querySpreadCustomerCountByCustomerId(long customerId) {
        return 0;
    }


    @Override
    public TcMember queryCustomerByRecommondCode(String code, long storeId) {
        return TcMemberMapper.queryCustomerByRecommondCode(code, storeId);
    }

    @Override
    public TcMember queryCustomerByAliOpenId(String code, long storeId) {
        return TcMemberMapper.queryCustomerByAliOpenId(code, storeId);
    }

    /**
     * 清除用户密码
     *
     * @param customers 用户信息
     * @return 返回用户信息
     */
    private List<TcMember> clearPassword(List<TcMember> customers) {
        customers.parallelStream().forEach(customer -> customer.clearPassword());
        return customers;
    }

  

    /**
     * 查询会员
     *
     * @param id 会员ID
     * @return 会员
     */
    @Override
    public TcMember selectTcMemberById(Long id) {
        return TcMemberMapper.selectTcMemberById(id);
    }

    @Override
    public TcMember queryCustomerByh5OpenId(String openid, long storeId) {
        return TcMemberMapper.queryCustomerByh5OpenId(openid, storeId);
    }

    @Override
    public TcMember queryCustomerByappOpenId(String openid, long storeId) {
        return TcMemberMapper.queryCustomerByappOpenId(openid, storeId);
    }

    @Override
    public TcMember queryCustomerByappletOpenId(String openid, long storeId) {
        return TcMemberMapper.queryCustomerByappletOpenId(openid, storeId);
    }

    /**
     * 查询会员列表
     *
     * @param TcMember 会员
     * @return 会员
     */
    @Override
    public List<TcMember> selectTcMemberList(TcMember TcMember) {
        return TcMemberMapper.selectTcMemberList(TcMember);
    }

    /**
     * 新增会员
     *
     * @param TcMember 会员
     * @return 结果
     */
    @Override
    public int insertTcMember(TcMember TcMember) {
        //设置自己的推荐码
        TcMember.addSelfRecommondCode();

        // 如果有推荐人 则查询推荐人信息
        if (TcMember.hasRecommonded()) {
            // 推荐人
            TcMember recommonded = TcMemberMapper.queryCustomerByRecommondCode(TcMember.getRecommondCode(), TcMember.getStoreId());

            // 如果推荐人不存在  则返回错误
            if (Objects.isNull(recommonded)) {
                log.error("addCustomer fail due to recommoned is not exist...and code:{}", TcMember.getRecommondCode());
                return -10;
            }
            // 设置推荐人的会员id
            TcMember.setRecommended(recommonded.getId());
            TcMember.setInterest(recommonded.getNickname());
            // 设置会员的二级推荐人/ 推荐人的推荐人
            TcMember.setSRecommended(recommonded.getRecommended());
        }
        TcMember.setPassword(mojinPasswordEncoder.encode(TcMember.getPassword()));

        TcMember.setCreateTime(DateUtils.getNowDate());
        return TcMemberMapper.insertTcMember(TcMember);
    }

    /**
     * 修改会员
     *
     * @param TcMember 会员
     * @return 结果
     */
    @Override
    public int updateTcMember(TcMember TcMember) {
        return TcMemberMapper.updateTcMember(TcMember);
    }

    /**
     * 批量删除会员
     *
     * @param ids 需要删除的会员ID
     * @return 结果
     */
    @Override
    public int deleteTcMemberByIds(Long[] ids) {
        return TcMemberMapper.deleteTcMemberByIds(ids);
    }

    /**
     * 删除会员信息
     *
     * @param id 会员ID
     * @return 结果
     */
    @Override
    public int deleteTcMemberById(Long id) {
        return TcMemberMapper.deleteTcMemberById(id);
    }


    @Override
    @Transactional
    public int registerCustomer(long storeId, String mobile, String password, String code, String originCode, String recommondCode) {
        logger.debug("registerCustomer and mobile :{} \r\n code:{} \r\n: originCode{} \r\n recommondCode:{}", mobile, code, originCode, recommondCode);

        if (StringUtils.isEmpty(code)) {
            logger.error("registerCustomer fail due to code is error...");
            return -1;
        }

        if (StringUtils.isEmpty(mobile) || StringUtils.isEmpty(password)) {
            logger.error("registerCustomer fail due to mobile or password is empty...");
            return -2;
        }

        // 判断手机号码是否存在
        if (this.isMobileExist(mobile, storeId) != 0) {
            logger.error("registerCustomer fail due to mobile is exist");
            return -3;
        }

        // 校验验证码是否正确
        if (!code.equals(originCode)) {
            logger.error("registerCustomer fail due to code is error...");
            return -1;
        }

        // 进行会员注册
        return this.addCustomer(TcMember.buildAppRegisterCustomer(storeId, mobile, password, recommondCode));


    }

}
